package cn.smile.business.msg.impl;

import cn.smile.bean.dto.core.SysUserDTO;
import cn.smile.bean.dto.msg.NoticeDTO;
import cn.smile.bean.entity.msg.Notice;
import cn.smile.bean.form.msg.notice.NoticeAddForm;
import cn.smile.business.core.ISysUserService;
import cn.smile.business.msg.INoticeService;
import cn.smile.commons.constant.NumberConstant;
import cn.smile.commons.domain.BaseServiceImpl;
import cn.smile.commons.enums.msg.NoticeHandleEnum;
import cn.smile.commons.exceptions.BusinessException;
import cn.smile.commons.response.MyResponseCode;
import cn.smile.repository.msg.NoticeMapper;
import cn.smile.utils.BeanCopy;
import cn.smile.utils.UserUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
public class NoticeServiceImpl extends BaseServiceImpl<NoticeMapper, Notice> implements INoticeService {

    @Resource
    private ISysUserService userService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addNotice(NoticeAddForm form) {
        log.info("[NoticeServiceImpl].[addNotice] ------> 新增系统公告 Start, form = {}", JSON.toJSONString(form));
        //1.先将之前的全部未处理公告设置为系统处理
        List<Notice> oldNotices = baseMapper.selectList(new QueryWrapper<Notice>().lambda().eq(Notice::getDeleted, Boolean.FALSE).eq(Notice::getHandleFlag, NoticeHandleEnum.UN_HANDLE.getSn()));
        if (!CollectionUtils.isEmpty(oldNotices)) {
            for (Notice entity : oldNotices) {
                entity.setHandleFlag(NoticeHandleEnum.SYSTEM_HANDLE.getSn());
                super.addBaseCol(entity);
                baseMapper.updateById(entity);
            }
        }
        //2.查询全部用户列表写入新公告
        List<SysUserDTO> userList = userService.getAllEnableUser();
        int insertNum = NumberConstant.ZERO;
        if (!CollectionUtils.isEmpty(userList)) {
            Notice baseEntity = BeanCopy.copyBean(form, Notice.class);
            baseEntity.setSendTime(LocalDateTime.now());
            baseEntity.setReadFlag(Boolean.FALSE);
            baseEntity.setHandleFlag(NoticeHandleEnum.UN_HANDLE.getSn());
            super.addBaseCol(baseEntity);
            for (SysUserDTO user : userList) {
                Notice entity = BeanCopy.copyBean(baseEntity, Notice.class);
                entity.setReceiveUserId(user.getId());
                insertNum += baseMapper.insert(entity);
            }
        }
        log.info("[NoticeServiceImpl].[addNotice] ------> 新增系统公告 End, insertNum = {}", insertNum);
        return Boolean.TRUE;
    }

    @Override
    public NoticeDTO getMyNotice() {
        log.info("[NoticeServiceImpl].[getMyNotice] ------> 登录用户获取未读公告 Start");
        LambdaQueryWrapper<Notice> qw = new QueryWrapper<Notice>().lambda().eq(Notice::getDeleted, Boolean.FALSE);
        qw.eq(Notice::getHandleFlag, NoticeHandleEnum.UN_HANDLE.getSn());
        qw.eq(Notice::getReadFlag, Boolean.FALSE);
        qw.eq(Notice::getReceiveUserId, UserUtil.getUserInfo().getId());
        List<Notice> baseList = baseMapper.selectList(qw);
        NoticeDTO dto = null;
        if (!CollectionUtils.isEmpty(baseList)) {
            dto = BeanCopy.copyBean(baseList.get(NumberConstant.ZERO), NoticeDTO.class);
        }
        log.info("[NoticeServiceImpl].[getMyNotice] ------> 登录用户获取未读公告 End");
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean readNotice(String id) {
        log.info("[NoticeServiceImpl].[readNotice] ------> 用户阅读公告 Start, id = {}", id);
        Notice entity = baseMapper.selectOne(new QueryWrapper<Notice>().lambda().eq(Notice::getDeleted, Boolean.FALSE).eq(Notice::getId, id));
        if (ObjectUtils.isEmpty(entity)) {
            throw new BusinessException(MyResponseCode.RESULT_DATA_NONE);
        }
        entity.setReadFlag(Boolean.TRUE);
        entity.setReadTime(LocalDateTime.now());
        entity.setHandleFlag(NoticeHandleEnum.USER_HANDLE.getSn());
        super.updateBaseCol(entity);
        int updateNum = baseMapper.updateById(entity);
        log.info("[NoticeServiceImpl].[readNotice] ------> 用户阅读公告 End, updateNum = {}", updateNum);
        return updateNum > NumberConstant.ZERO;
    }
}
